﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Security.Cryptography;

namespace MercuryFE
{
    /*
    whole bunch of classes used for data loads and manipulation... could probably get away with using structs or types or whatever the
     hell they are.
     * */
    public class GameMenu
    {
        public string GameName { get; set; }
        public string EmulatorName { get; set; }
        public string Description { get; set; }
        public string RomFile { get; set; }
        public int GameID { get; set; }
        public int MenuID { get; set; }
    }

    // Define other methods and classes here
    public class Category
    {
        public string romName { get; set; }
        public string categoryName { get; set; }
    }

    class Config
    {
        public string mameBuild { get; set; }
        public bool mameDebug { get; set; }
        public string controlsVersion { get; set; }
        public string controlsTime { get; set; }
    }

    
        //public string nplayers { get; set; }

    public class ControlsInfo
    {
        public string romName { get; set; }
        public string gameName { get; set; }
        public int numplayers { get; set; }
        public string miscdetails { get; set; }
        public bool alternating { get; set; }
        public bool mirrored { get; set; }
        public bool usesservice { get; set; }
        public bool tilt { get; set; }
        public bool cocktail { get; set; }
    }

    public class GameDetail
    {
        public string romName { get; set; }
        public string gameName { get; set; }
        public string cloneOf { get; set; }
        public string romOf { get; set; }

        public string description { get; set; }
        public string year { get; set; }
        public string manufacturer { get; set; }
        public string sourceFile { get; set; }
        public string driverStatus { get; set; }
        public string driverEmulation { get; set; }
        public string driverColor { get; set; }
        public string driverSound { get; set; }
        public string driverGraphic { get; set; }
        public string driverSavestate { get; set; }
        public string driverPalettesize { get; set; }
        //public string history { get; set; }
        public string displayType { get; set; }
        public int? rotate { get; set; }
        public bool isBios { get; set; }



        //public List<Player> players { get; set; }
        //public List<string> categories { get; set; }
        //public List<Command> commands { get; set; }

        /// <summary>
        /// Returns an md5 hash to use for change checking
        /// </summary>
        /// <returns></returns>
        public string getHash()
        {
            return LauncherLib.GetMd5Sum(
              romName ?? ""
            + gameName ?? ""
            + cloneOf ?? ""
            + romOf ?? ""
            + description ?? ""
            + year ?? ""
            + sourceFile ?? ""
            + manufacturer ?? ""
            + driverStatus ?? ""
            + driverEmulation ?? ""
            + driverColor ?? ""
            + driverSound ?? ""
            + driverGraphic ?? ""
            + driverSavestate ?? ""
            + driverPalettesize ?? ""
            + displayType ?? ""
            + (rotate == null ? "" : rotate.ToString())
            + isBios.ToString() 
            );
        }
    }

    public class NPlayer
    {
        public string romName { get; set; }
        public string nPlayers { get; set; }
    }

    public class GamePlayer
    {
        public string romName { get; set; }
        public List<Player> players { get; set; }
    }

    public class Player
    {
        public string number { get; set; }
        public int numButtons { get; set; }
        public List<Label> labels { get; set; }
        public List<Control> controls { get; set; }
    }

    public class Label
    {
        public string name { get; set; }
        public string value { get; set; }
        public string color { get; set; }


        public override string  ToString()
        {
            return (name == null ? "" : name.ToUpper().Trim()) + (value == null ? "" : value.ToUpper().Trim()) + (color == null ? "" : color.ToUpper().Trim());
         }


    }

    public class LabelComparer : IEqualityComparer<Label>
    {

        public bool Equals(Label x, Label y)
        {
            return (x.ToString() == y.ToString());
        }

        public int GetHashCode(Label obj)
        {
            return obj.ToString().GetHashCode();
        }

    }

    public class IntArrayComparer : IEqualityComparer<int[]>
    {

        public bool Equals(int[] x, int[] y)
        {
            // if lengths aren't same - no match
            if (x.Length != y.Length)
                return false;


            for (int i = 0; i < x.Length; i++)
            {
                // if any members are different, no match
                if (x[i] != y[i])
                {
                    return false;
                }
            }
            return true;
        }

        public int GetHashCode(int[] obj)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < obj.Length; i++)
            {
                sb.Append(obj[i].ToString());
            }
            return sb.ToString().GetHashCode();
        }

    }

    public class StringArrayComparer : IEqualityComparer<string[]>
    {

        public bool Equals(string[] x, string[] y)
        {
            // if lengths aren't same - no match
            if (x.Length != y.Length)
                return false;


            for (int i = 0; i < x.Length; i++)
            {
                // if any members are different, no match
                if (x[i] != y[i])
                {
                    return false;
                }
            }
            return true;
        }

        public int GetHashCode(string[] obj)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < obj.Length; i++)
            {
                sb.Append((obj[i] != null ? obj[i].ToString() : ""));
            }
            return sb.ToString().GetHashCode();
        }

    }


    public class Control
    {
        public string name { get; set; }
        public List<string> constants { get; set; }
        public List<string> buttons { get; set; }

    }


    class History
    {
        public List<string> romName { get; set; }
        public string url { get; set; }
        public string content { get; set; }
    }


    public class Command
    {
        // place into DB
        public int MameCommandSetID { get; set; }
        public string heading { get; set; }
        public string content { get; set; }
        public int order { get; set; }

        // used to populate another lookup table
        public List<string> romNames { get; set; }

    }


    class SearchPath
    {
        public int EmulatorID { get; set; }
        public int EmulatorPathID { get; set; }
        public string Path { get; set; }
        public string PathType { get; set; }
        public string SearchPattern { get; set; }
        public bool IncludeSubPaths { get; set; }
        public bool IsMame { get; set; }
    }


    class SearchGame
    {
        public string Emulator { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string RomFile { get; set; }
        public string DriverStatus { get; set; }
        public string CloneOf { get; set; }
        public string NPlayers { get; set; }
        public bool IsMame { get; set; }

        public string Category { get; set; }

        public int? NumPlayers {get; set; }
        public int? MameRomID { get; set; }

        public int GameID { get; set; }
        public string SourceFile { get; set; }
    }


    // used by populateGameEntries
    public class GameEntry
    {
        public int gameId { get; set; }
        public int emulatorId { get; set; }
        public string name { get; set; }
        public string romFile { get; set; }
        public int romPathId { get; set; }
        public string romSubPath { get; set; }
        public string snapshotFile { get; set; }
        public int? snapshotPathId { get; set; }
        public string snapshotSubPath { get; set; }
        public string movieFile { get; set; }
        public int? moviePathId { get; set; }
        public string movieSubPath { get; set; }
        public int? mameRomId { get; set; }



        public string hash
        {
            get
            {
                UnicodeEncoding ue = new UnicodeEncoding();

                //'Retrieve a byte array based on the source text
                StringBuilder sb = new StringBuilder();
                //sb.Append(emulatorId.ToString());
                sb.Append(name.ToString());
                //sb.Append(romFile.ToString());
                sb.Append(romPathId.ToString());
                sb.Append(romSubPath.ToString());
                sb.Append(snapshotFile ?? "");
                sb.Append(snapshotPathId.ToString());
                sb.Append(snapshotSubPath ?? "");
                sb.Append(movieFile ?? "");
                sb.Append(moviePathId.ToString());
                sb.Append(movieSubPath ?? "");
                sb.Append(mameRomId.ToString());

                byte[] byteSourceText = ue.GetBytes(sb.ToString());
                MD5CryptoServiceProvider Md5 = new MD5CryptoServiceProvider();
                byte[] ByteHash = Md5.ComputeHash(byteSourceText);

                return Convert.ToBase64String(ByteHash);
            }
        }
    }

    public class EmulatorConfig
    {
        public int EmulatorID { get; set; }
        public string Name { get; set; }
        public string Executable { get; set; }
        public string Location { get; set; }
        public string Description { get; set; }
        public string ConfigurationFile { get; set; }
        public string Arguments { get; set; }
        public string ImageName { get; set; }
        public bool IsMame { get; set; }
        public string ConfigDescFile { get; set; }
        public string PreLoad { get; set; }
        public string PostLoad { get; set; }
        public Dictionary<string,string> KeyMappings { get; set; }

        public List<EmulatorPathConfig> RomPaths { get; set; }
        public List<EmulatorPathConfig> SnapPaths { get; set; }
        public List<EmulatorPathConfig> MoviePaths { get; set; }

        public bool RomIncludeSubPaths { get; set; }
        public string RomSearchPattern { get; set; }
        public bool SnapIncludeSubPaths { get; set; }
        public string SnapSearchPattern { get; set; }
        public bool MovieIncludeSubPaths { get; set; }
        public string MovieSearchPattern { get; set; }

        public EmulatorConfig()
        {
            RomPaths = new List<EmulatorPathConfig>();
            SnapPaths = new List<EmulatorPathConfig>();
            MoviePaths = new List<EmulatorPathConfig>();
        }

        public void StringToKeyMapping(string value)
        {
            this.KeyMappings = LauncherLib.StringToKeyMapping(value);
        }

        public string KeyMappingString()
        {
            return LauncherLib.KeyMappingToString(this.KeyMappings);

        }
    }

    public class EmulatorPathConfig
    {
        public int EmulatorPathID { get; set; }
        public string Path { get; set; }
        public string SearchPattern { get; set; }
        public bool IncludeSubPaths { get; set; }

        public EmulatorPathConfig()
        {

        }

        public EmulatorPathConfig(string path, string searchPattern, bool includeSubPaths)
        {
            this.EmulatorPathID = -1;
            this.Path = path;
            this.SearchPattern = searchPattern;
            this.IncludeSubPaths = includeSubPaths;
        }
    }

    public class ProgramConfig
    {
        public string Name {get; set;}
        public string Value {get; set;}
        public string DataType {get; set;}
        public string TypeSettings { get; set; }
        public string Description { get; set; }
        public string Category { get; set; }

    }

    public struct mameRomCompare
    {
        public int MameRomID;
        public string Hash;

        //public mameRomCompare()
        //{
        //    MameRomID = -1;
        //    Hash = "";
        //}

        public mameRomCompare(int mameRomID, string hash)
        {
            MameRomID = mameRomID;
            Hash = hash;
        }

    }


    public class CustomGame
    {
        public int? GameID;
        public string Name;
        public string Description;
        //public string ExecutableLocation;
        public string Executable;
        //public string MovieLocation;
        public string Movie;
        //public string SnapshotLocation;
        public string Snapshot;
        public string PreLoad;
        public string PostLoad;
        public Dictionary<string, string> KeyMappings;

        public void StringToKeyMapping(string value)
        {
            this.KeyMappings = LauncherLib.StringToKeyMapping(value);
        }

        public string KeyMappingString()
        {
            return LauncherLib.KeyMappingToString(this.KeyMappings);

        }
    }


  
}
